<?php

/**
 * Class Core_Redis
 * @package Core
 */
class Core_Redis {
    // Singleton instances
    protected static $_instance = array();
    // cache
    protected static $_shardTotal = array();

    /**
     * @param string $name
     * @param mixed $shard_key
     * @return Redis
     */
    public static function getInstance($name = 'default', $shard_key = false) {

        if ($shard_key !== false) {
            if (!isset(self::$_shardTotal[$name])) {
                $conf = Core_Config::get("redis.{$name}");
                self::$_shardTotal[$name] = count($conf);
            }
            $target = crc32($shard_key) % self::$_shardTotal[$name];
            $name = "{$name}.{$target}";
        }

        /* @var $redis Redis */
        if (!isset(self::$_instance[$name])) {
            $redis = self::_connect($name);
        } else {
            $redis = self::$_instance[$name];
        }

        try {
            $ping = $redis->ping();
            //非newroad error exception handler 模式
            if (!$ping) {
                $redis = self::_connect($name);
                Core_Log::logErr('redis reconnect');
            }
        } catch (Exception $e) {
            //try once again
            $redis = self::_connect($name);
            Core_Log::logErr($e);
        }

        return $redis;
    }

    /**
     * @param $name
     * @return Redis
     */
    protected static function _connect($name) {
        $conf = Core_Config::get("redis.{$name}");
        $redis = new Redis();
        $redis->connect($conf['host'], $conf['port']);
        if (!empty($conf['database'])) {
            $redis->select($conf['database']);
        }
        self::$_instance[$name] = $redis;
        return $redis;
    }

    public static function closeAll() {
        /* @var $redis Redis */
        foreach (self::$_instance as $redis) {
            $redis->close();
        }
        self::$_instance = array();
    }
}
